<template>
  <div>
    <!-- v-model: 关联底部加载状态
      loading: true(转圈)
      loading: false(不再转圈)
        finished: 数据全都加载完成，
      true: 加载完成后不再触发load事件 (底部显示finished-text的文字)
      false: 触底继续触发load事件

      @load事件: 组件滚动底部时, 内部会调用load事件触发

      immediate-check:
      true - 上来默认检查一次触底
      false - 上来不检查触底

     -->
    <van-pull-refresh v-model="refreshing" @refresh="onRefresh">
      <van-list
        v-model="loading"
        :finished="finished"
        finished-text="没有更多了"
        :immediate-check="false"
        @load="onLoad"
      >
        <article-item
          v-for="obj in articleList"
          :key="obj.art_id"
          :artObj="obj"
          @click="artDetailFn(obj.art_id)"
        >
        </article-item>
      </van-list>
    </van-pull-refresh>
  </div>
</template>

<script>
// 目标: 文章列表铺设
// 1. 找到接口, 写api/index.js->接口方法
// 2. ArticleList引入, 发起文章列表请求拿到数据
// 3. v-for遍历article-item, 传入数据对象展示数据

// 组件套路
// 1. 找到类似的, 复制过来, 使用运行看效果
// 2. 删除无用的
// 3. 修改(读属性/直接改文字/标签数量)
// 4. 其他....

// 目标: 底部加载更多组件 (van-list)
// 重要1: 当组件滚动到底部时，会触发 load 事件并将 loading 设置成 true
// 重要2: finished: 加载完成，加载完成后不再触发load事件
// 重要3: 初始化的时候, 就判定是否触底(数据是网络请求回来的-异步, 默认触发load一次)
// 重要4: 数据加载完毕, loading: false(保证下次触底还能执行load事件)

// 和tabs配合使用van-list小问题:
// 复现: 前一页, 往下滚动, 然后再切换到别的频道, 会导致van-list上来又触发@load事件
// 原因: :immediate-check无法阻止滚动事件的监听效果
// 前一页, 网页滚动条滚动下边去了, tab下一页没有那么高(默认上来数据没回来, 没有滚动条的)
// 滚动条从下边, 自己又滚动回来了

// 目标: 触底, 在发请求, 拿到下一页数据
// 1. 接口文档: 发现需要传递timestamp时间戳
// 下一页数据需要传递上一次接口返回的pre_timestamp的时间值
// 2. data函数里nextTime, 专门用于保存紧挨着的上一次的pre_timestamp的值
// 3. onLoad触底加载更多事件方法中, 把nextTime传入API接口方法内
// 4. 修改api/index.js相应接口, 接收timestamp值(不能固定的)

// 目标: 解决默认触发2次的bug, 解决加载更多数据
// 1. list组件immediate-check:false (关闭立即检查)
// 2. onLoad方法里, 要把新的数据和原数据, 进行合并(数据更多)
// 3. 异步加载完毕以后loading:false (保证下次触底还能执行load事件)
// 4. 判断没有更多数据了, finished: true(加载完成)

// 目标: 下拉刷新(顶部刷新)
// js原生实现:
// 移动端特有事件名: touchstart touchmove touchend
// 获取手指在屏幕的坐标点, 移动后, 手指坐标点, 手指离开屏幕触发touchend
// 获取到手指偏移量, 修改标签的位移量 (加c3过渡动画)
// 采用PullRefresh的组件
// 1. 找到包在van-list组件外面
// 2. 把变量和方法定义好
// 3. 刷新方法里, 清空数组, 把nextTime=new Date(), 重新请求一次新的数据
// 4. refreshing的状态: false

import ArticleItem from '@/components/ArticleItem.vue'
import { getArticleListAPI } from '@/api'
export default {
  props: {
    channelId: Number
  },
  components: {
    ArticleItem
  },
  data () {
    return {
      articleList: [], // 文章列表
      list: [],
      loading: false, // 底部加载状态
      finished: false,
      nextTime: new Date(), // 下一页的文章列表-开头文章的发布时间(来自于上一次响应值里pre_timestamp)
      refreshing: false // 顶部刷新状态
    }
  },
  methods: {
    // 底部加载
    async onLoad () {
      // 异步更新数据, 获取文章列表
      // const res = await getArticleListAPI({
      //   channel_id: this.channelId,
      //   timestamp: this.nextTime
      // })
      // 知识点: res.data.data可能是null, 如果继续.results就报错了
      // 你需要用逻辑与前置判断, 前面.出来值了, 才能继续往下.
      // 更好的做法:
      // if (res.data.data && res.data.data.results && res.data.data.results.length === 0) {
      //   // 本次加载更多就无数据
      //   this.finished = true
      // }
      // if (res.data?.data?.results?.length === 0) {
      //   // 本次加载更多就无数据
      //   this.finished = true
      // }

      // this.articleList = [...this.articleList, ...res.data.data.results]
      // this.loading = false // 本次加载完毕(这样下次触底, 才能再出发load事件和onLoad方法)
      if (this.articleList.length > 0) {
        // 上来你先走created请求, 把数据拿回来铺设页面, 等用户真的滚动到下面了, 再次执行load事件, 这个判断有数据了, 我在请求下一页
        this.getArticleListFn()
      }
    },
    artDetailFn (artId) {
      this.$router.push({
        path: '/art_detail',
        query: {
          aid: artId
        }
      })
    },
    // 获取文章列表
    async getArticleListFn () {
      const res = await getArticleListAPI({
        channel_id: this.channelId,
        timestamp: this.nextTime
      })
      // if (res.data?.data?.results?.length === 0) {
      //   // 本次加载更多就无数据
      //   this.finished = true
      // }

      this.articleList = [...this.articleList, ...res.data.data.results]
      // 如果pre_timestamp本次为null, 没有下一页的数据
      if (res.data?.data?.pre_timestamp === null) {
        this.finished = true
        this.nextTime = null
      } else {
        this.nextTime = res.data.data.pre_timestamp
      }
      this.loading = false // 本次加载完毕(这样下次触底, 才能再出发load事件和onLoad方法)
      setTimeout(() => { // 完全为了看一眼顶部加载转圈效果
        this.refreshing = false // 本次刷新完毕
      }, 1000)
    },
    // 顶部刷新
    onRefresh () {
      // 刷新新的数据回来, 原数组清空
      // 再向后台发送一次请求, timestamp改回车最新的时间
      this.articleList = []
      this.nextTime = new Date()
      this.getArticleListFn()
    }
  },
  created () {
    // tab在切换的时候, 如果是第一次出现, 会走一次created
    // 切回去的时候created不走了, 但是标签没动(横向的位移)
    // res.data (axios内, 把后台返回的数据对象放到了data字段下)
    // 后台数据对象里, 还有个data, 所以需要.2次data
    this.getArticleListFn()
  }
}
</script>

<style>
</style>
